package com.dmwork.service.work.mq.receiver;

import com.dmwork.common.base.result.ExceptionUtils;
import com.dmwork.service.work.entity.Work;
import com.dmwork.service.work.service.WorkService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Transactional
@Component
public class MessageReceiver {

    @Autowired
    private WorkService workService;

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(
                            value = "${spring.rabbitmq.custom.receiver.on-work-collect-count-change-message-receive.queue.name}",
                            durable = "${spring.rabbitmq.custom.receiver.on-work-collect-count-change-message-receive.queue.durable}",
                            arguments = {
                                    @Argument(
                                            name = "x-dead-letter-exchange",
                                            value = "${spring.rabbitmq.custom.receiver.on-work-collect-count-change-message-receive.x-dead-letter-exchange}"
                                    ),
                                    @Argument(
                                            name = "x-dead-letter-routing-key",
                                            value = "${spring.rabbitmq.custom.receiver.on-work-collect-count-change-message-receive.x-dead-letter-routing-key}"
                                    )
                            }
                    ),
                    exchange = @Exchange(
                            value = "${spring.rabbitmq.custom.receiver.exchange.name}",
                            type = "${spring.rabbitmq.custom.receiver.exchange.durable}",
                            durable = "${spring.rabbitmq.custom.receiver.exchange.type}",
                            ignoreDeclarationExceptions = "${spring.rabbitmq.custom.receiver.exchange.ignore-declaration-exceptions}"
                    ),
                    key = {"${spring.rabbitmq.custom.receiver.on-work-collect-count-change-message-receive.key}"}
            )
    })
    @RabbitHandler
    public void onWorkCollectCountChangeMessageReceive(Message<Map<String, Integer>> message, Channel channel) throws IOException {
        try {
            Map<String, Integer> payload = message.getPayload();
            List<Work> workList=new ArrayList<>(payload.size());
            for (Map.Entry<String, Integer> entry : payload.entrySet()) {
                Work work = new Work();
                work.setId(entry.getKey());
                work.setCollectCount(entry.getValue());
                workList.add(work);
            }
            workService.updateBatchById(workList);
            long deliveryTag= (long) message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
            channel.basicAck(deliveryTag, false);
        }catch (Exception e) {
            ExceptionUtils.getMessage(e);
            long deliveryTag= (long) message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
            channel.basicNack(deliveryTag, false, false);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }
//    @RabbitHandler
//    public void onWorkCollectCountChangeMessageReceive(Message<Map<String, Object>> message, Channel channel) throws IOException {
//        try {
//            Map<String, Object> payload = message.getPayload();
//            String workId= (String) payload.get("workId");
//            Integer changeCount= (Integer) payload.get("changeCount");
//            if (changeCount>0) {
//                workService.increaseCollectCount(workId);
//            }else if (changeCount<0) {
//                workService.decreaseCollectCount(workId);
//            }
//            long deliveryTag= (long) message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
//            channel.basicAck(deliveryTag, false);
//        }catch (Exception e) {
//            ExceptionUtils.getMessage(e);
//            long deliveryTag= (long) message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
//            channel.basicNack(deliveryTag, false, false);
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//        }
//    }

}
